package com.applcn.goods.service;

import cn.hutool.core.lang.Assert;
import com.applcn.core.base.Result;
import com.applcn.goods.constant.GoodsCheckStatusEnum;
import com.applcn.goods.constant.OnSaleStatusEnum;
import com.applcn.goods.constant.SkuShowStatusEnum;
import com.applcn.goods.constant.SnapshotStatusEnum;
import com.applcn.goods.dto.PublishGoodsDTO;
import com.applcn.goods.dto.PublishGoodsSkuDTO;
import com.applcn.goods.repo.entity.GoodsEntity;
import com.applcn.goods.repo.entity.GoodsSkuEntity;
import com.applcn.goods.repo.repository.GoodsRepository;
import com.applcn.goods.threadlocal.GoodsRequestContext;
import com.applcn.goods.threadlocal.GoodsRequestContextHolder;
import com.applcn.shop.client.ShopClient;
import com.applcn.shop.dto.ShopInfoDTO;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Comparator;
import java.util.List;

/**
 * com.applcn.goods.service
 * Description:
 *
 * @author: 大妖怪
 * @date: 2020-02-13 00:48
 */
@Service
@RequiredArgsConstructor
public class GoodsService {

    private final ShopClient shopClient;
    private final GoodsRepository goodsRepository;
    private final AsyncGoodsSkuService asyncGoodsSkuService;

    /**
     * 发布商品
     * <p>1.创建商品</p>
     * <p>2.创建sku</p>
     *
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Result publishGoods(PublishGoodsDTO dto) {
        OnSaleStatusEnum onSaleStatusEnum = OnSaleStatusEnum.getStatus(dto.getOnSaleStatus());
        Assert.notNull(onSaleStatusEnum, "销售状态不正确");
        GoodsRequestContext goodsRequestContext = GoodsRequestContextHolder.getLocalRequestContext();
        Long userId = goodsRequestContext.getUserId();
        Assert.notNull(userId, "用户未登录");
        Long merchantId = goodsRequestContext.getMerchantId();
        Assert.notNull(merchantId, "当前用户不是商户");
        Assert.notEmpty(dto.getSkuDTOList(), "请传入商品规格");
        // 查询店铺权限
        Result shopResult = shopClient.listShopByIds(Lists.newArrayList(dto.getShopId()));
        Assert.isTrue(shopResult.isSuccess(), "查询店铺失败");
        Assert.notNull(shopResult.getData(), "店铺不存");
        // 这里暂时强转，虽然不太优雅\
        List<ShopInfoDTO> shopInfoDTOList = (List<ShopInfoDTO>) shopResult.getData();
        ShopInfoDTO shopInfoDTO = shopInfoDTOList.get(0);
        Assert.isTrue(Objects.equal(shopInfoDTO.getMerchantId(), merchantId), "没有操作权限");
        GoodsEntity goodsEntity = new GoodsEntity();
        goodsEntity.setMerchantId(merchantId);
        goodsEntity.setShopId(dto.getShopId());
        goodsEntity.setName(dto.getName());
        goodsEntity.setMainPicUrls(dto.getMainPicUrls());
        goodsEntity.setIntroduce(dto.getIntroduce());
        goodsEntity.setIntroducePicUrls(dto.getIntroducePicUrls());
        goodsEntity.setDisplayMinPrice(dto.getSkuDTOList().stream().min(Comparator.comparing(PublishGoodsSkuDTO::getSellPrice))
                .get().getSellPrice());
        goodsEntity.setDisplayMaxPrice(dto.getSkuDTOList().stream().max(Comparator.comparing(PublishGoodsSkuDTO::getSellPrice))
                .get().getSellPrice());
        goodsEntity.setGoodsCheckStatus(GoodsCheckStatusEnum.APPLY);
        goodsEntity.setOnSaleStatus(onSaleStatusEnum);
        goodsRepository.save(goodsEntity);

        // 异步保存sku
        for (PublishGoodsSkuDTO publishGoodsSkuDTO:dto.getSkuDTOList()) {
            GoodsSkuEntity goodsSkuEntity = new GoodsSkuEntity();
            goodsSkuEntity.setMerchantId(merchantId);
            goodsSkuEntity.setShopId(dto.getShopId());
            goodsSkuEntity.setGoodsId(goodsEntity.getId());
            goodsSkuEntity.setSkuPicUrl(publishGoodsSkuDTO.getSukPicUrl());
            goodsSkuEntity.setPrice(publishGoodsSkuDTO.getPrice());
            goodsSkuEntity.setSellPrice(publishGoodsSkuDTO.getSellPrice());
            goodsSkuEntity.setSkuCount(publishGoodsSkuDTO.getSkuCount());
            goodsSkuEntity.setSkuShowStatus(SkuShowStatusEnum.SHOW);
            goodsSkuEntity.setSnapshotStatus(SnapshotStatusEnum.FORMAL);
            asyncGoodsSkuService.saveSku(goodsSkuEntity);
        }

        return Result.ok();
    }
}
